<script setup lang="ts">
import { ref, computed, onMounted } from 'vue';
import { useRoute } from 'vue-router';
import { useTabs } from '@vben/hooks';
import { Page } from '@vben/common-ui';
import {
  Card,
  Button,
  Space,
  Modal,
  Input,
  Select,
  Row,
  Col,
  theme,
  InputNumber,
  message,
} from 'ant-design-vue';
import { DeleteOutlined, ArrowDownOutlined } from '@ant-design/icons-vue';
import { cloneDeep } from 'lodash-es';
import { configInfo, configUpdate } from '#/api/rule/config';
import type { ConfigVO, ConfigForm, ActionItem } from '#/api/rule/config/model';
import type { ManageVO } from '#/api/survey/manage/model';
import { surveyListAll } from '#/api/survey/manage';
import { wxMsgTempListAll } from '#/api/system/wxMsgTemp';

// =============================================================================
// Types
// =============================================================================

// UI-specific Action, with a unique id for v-for keys
interface UIAction extends ActionItem {
  __id: string;
}

// UI-specific Rule, using the UIAction type
interface UIRule extends Omit<ConfigVO, 'actionConfig'> {
  actionConfig: {
    actions: UIAction[];
  };
}
// 量表列表（接口获取）
const surveyList = ref<ManageVO[]>([]);
const wxTemplateOptions = ref<{ label: string; value: string }[]>([]);

// =============================================================================
// Node Definitions
// =============================================================================
const CONDITION_NODES = [
  {
    node: 'checkConsecutiveNoCheckIn',
    nodeLabel: '连续未打卡',
    triggerType: 'SCHEDULED',
    params: [
      {
        key: 'taskType',
        paramLabel: '任务类型',
        type: 'SELECT',
        required: true,
        options: [
          { label: '运动', value: 'EXERCISE' },
          { label: '用药', value: 'MEDICATION' },
        ],
      },
      {
        key: 'consecutiveDays',
        paramLabel: '连续天数',
        type: 'NUMBER_INPUT',
        required: true,
        addonAfter: '天',
      },
    ],
  },
  {
    node: 'checkBloodGlucose',
    nodeLabel: '血糖值高于',
    triggerType: 'EVENT_DRIVEN',
    params: [
      {
        key: 'timing',
        paramLabel: '测量时间',
        type: 'SELECT',
        required: true,
        options: [
          { label: '空腹', value: 'FASTING' },
          { label: '餐后', value: 'POSTPRANDIAL' },
        ],
      },
      {
        key: 'threshold',
        paramLabel: '阈值',
        type: 'NUMBER_INPUT',
        required: true,
        addonAfter: 'mmol/L',
      },
    ],
  },
  {
    node: 'checkBloodGlucoseLow',
    nodeLabel: '血糖值低于',
    triggerType: 'EVENT_DRIVEN',
    params: [
      {
        key: 'timing',
        paramLabel: '测量时间',
        type: 'SELECT',
        required: true,
        options: [
          { label: '空腹', value: 'FASTING' },
          { label: '餐后', value: 'POSTPRANDIAL' },
        ],
      },
      {
        key: 'threshold',
        paramLabel: '阈值',
        type: 'NUMBER_INPUT',
        required: true,
        addonAfter: 'mmol/L',
      },
    ],
  },
];

const ACTION_NODES = computed(() => [
  {
    node: 'sendPushAction',
    nodeLabel: '发送微信提醒',
    params: [
      {
        key: 'templateId',
        paramLabel: '消息模板',
        type: 'SELECT',
        required: true,
        options: wxTemplateOptions.value,
      },
    ],
  },
  {
    node: 'createFollowUpAction',
    nodeLabel: '创建随访任务',
    params: [
      {
        key: 'taskName',
        paramLabel: '任务名称',
        type: 'SELECT',
        required: true,
        options: surveyList.value,
      },
      {
        key: 'priority',
        paramLabel: '优先级',
        type: 'SELECT',
        required: true,
        options: [
          { label: '高', value: 'HIGH' },
          { label: '中', value: 'MEDIUM' },
          { label: '低', value: 'LOW' },
        ],
      },
    ],
  },
  {
    node: 'recordGlucoseAbnormalEvent',
    nodeLabel: '记录血糖异常事件',
    params: [],
  },
  {
    node: 'recordNonComplianceEvent',
    nodeLabel: '记录非依从性事件',
    params: [],
  },
  {
    node: 'recordFollowUpEvent',
    nodeLabel: '记录随访事件',
    params: [],
  },
]);

// =============================================================================
// State
// =============================================================================
const { token } = theme.useToken();
const route = useRoute();
const { closeCurrentTab } = useTabs();
const formData = ref<UIRule>();
const isLoading = ref(true);

const availableConditions = computed(() => {
  if (!formData.value) return [];
  return CONDITION_NODES.filter(
    (c) => c.triggerType === formData.value?.triggerType,
  ).map((c) => ({ label: c.nodeLabel, value: c.node }));
});

const selectedConditionNode = computed(() => {
  if (!formData.value?.conditionConfig?.node) return null;
  return CONDITION_NODES.find(
    (n) => n.node === formData.value!.conditionConfig.node,
  );
});

const isNodeSelectorVisible = ref(false);
// 获取随访量表列表
const getSurveyList = async () => {
  const list = await surveyListAll();
  surveyList.value = list.map((item) => {
    return {
      ...item,
      label: item.name,
      value: item.key,
    };
  });
};

// 获取微信消息模板列表
const getWxTemplates = async () => {
  const templates = await wxMsgTempListAll();
  wxTemplateOptions.value = templates.map((item) => ({
    label: item.title,
    value: item.templateId,
  }));
};

// =============================================================================
// Functions
// =============================================================================

async function getRuleDetails(id: string | number) {
  isLoading.value = true;
  try {
    const record = await configInfo(id as string);

    if (record) {
      // Normalize the record to ensure configs are not null
      const conditionConfig = record.conditionConfig || {};
      const actionConfig = record.actionConfig || { actions: [] };

      // Assign the processed data to formData
      formData.value = {
        ...record,
        conditionConfig,
        actionConfig: {
          actions: actionConfig.actions.map((action) => ({
            ...action,
            __id: `action_${Math.random()}`,
          })),
        },
      };
    } else {
      // Handle case where ID is valid but no record is found
      formData.value = undefined;
    }
  } catch (e) {
    console.error(e);
    formData.value = undefined;
  } finally {
    isLoading.value = false;
  }
}

onMounted(() => {
  const id = route.params.id as string;
  if (id) {
    getRuleDetails(id);
    getSurveyList();
    getWxTemplates();
  }
});

// Validates the currently active rule's configuration.
const validateActiveRule = (): boolean => {
  if (!formData.value) return false;

  const condDef = selectedConditionNode.value;
  if (condDef) {
    for (const param of condDef.params) {
      if (param.required && !formData.value.conditionConfig[param.key]) {
        message.error(`请填写条件参数: ${param.paramLabel}`);
        return false;
      }
    }
  }

  if (formData.value.actionConfig.actions) {
    for (const action of formData.value.actionConfig.actions) {
      const def = ACTION_NODES.value.find((n) => n.node === action.node);
      if (def) {
        for (const param of def.params) {
          if (param.required && !action[param.key]) {
            message.error(`请填写动作参数: ${param.paramLabel}`);
            return false;
          }
        }
      }
    }
  }

  return true;
};

// Saves the currently active rule (handles updates).
const saveRule = async () => {
  if (!formData.value) {
    message.error('没有规则可以保存');
    return;
  }
  if (!validateActiveRule()) return;

  // Create a payload by omitting the frontend-only __id from actions
  const payload = cloneDeep(formData.value);
  if (payload.actionConfig?.actions) {
    payload.actionConfig.actions.forEach((act: any) => delete act.__id);
  }

  await configUpdate(payload as ConfigForm);
  // Re-fetch data to ensure consistency
  getRuleDetails(formData.value.id);
};

const handleConditionNodeChange = () => {
  if (!formData.value) return;
  const oldNode = formData.value.conditionConfig.node;
  // Reset params when node changes
  formData.value.conditionConfig = { node: oldNode };
};

const showNodeSelector = () => {
  isNodeSelectorVisible.value = true;
};

const handleNodeSelected = (node: string) => {
  if (!formData.value) return;
  const newAction: UIAction = {
    __id: `${node}_${Date.now()}`,
    node: node,
  };
  formData.value.actionConfig.actions.push(newAction);
  isNodeSelectorVisible.value = false;
};

const removeAction = (index: number) => {
  formData.value?.actionConfig.actions.splice(index, 1);
};

const getActionNodeDefinition = (node?: string) => {
  if (!node) return undefined;
  return ACTION_NODES.value.find((n) => n.node === node);
};
</script>

<template>
  <Page :loading="isLoading" :auto-content-height="true">
    <div class="rule-config-panel flex h-full flex-col" v-if="formData">
      <!-- Scrollable Content Area -->
      <div class="flex-1 overflow-y-auto p-6">
        <!-- IF/触发条件 -->
        <Card title="IF / 触发条件" class="config-section">
          <div class="form-group">
            <label>条件类型:</label>
            <Select
              v-model:value="formData.conditionConfig.node"
              :options="availableConditions"
              placeholder="请选择触发条件"
              class="w-full"
              @change="handleConditionNodeChange"
            />
          </div>

          <div
            v-for="param in selectedConditionNode?.params"
            :key="param.key"
            class="form-group"
          >
            <label>{{ param.paramLabel }}:</label>
            <Input
              v-if="param.type === 'TEXT_INPUT'"
              v-model:value="formData.conditionConfig[param.key]"
            />
            <InputNumber
              v-if="param.type === 'NUMBER_INPUT'"
              v-model:value="formData.conditionConfig[param.key]"
              class="w-full"
              :addon-after="param.addonAfter"
            />
            <Select
              v-if="param.type === 'SELECT'"
              v-model:value="formData.conditionConfig[param.key]"
              :options="param.options"
              class="w-full"
            />
            <Input.TextArea
              v-if="param.type === 'TEXT_AREA'"
              v-model:value="formData.conditionConfig[param.key]"
            />
          </div>
        </Card>

        <div class="my-4 text-center">
          <ArrowDownOutlined
            :style="{ fontSize: '24px', color: token.colorTextSecondary }"
          />
        </div>

        <!-- THEN/执行动作 -->
        <Card title="THEN / 执行动作" class="config-section">
          <template #extra>
            <Button type="primary" @click="showNodeSelector">+ 添加动作</Button>
          </template>
          <div
            v-if="
              !formData.actionConfig ||
              formData.actionConfig.actions.length === 0
            "
            class="py-8 text-center text-gray-400"
          >
            暂无动作，请点击右上角按钮添加
          </div>
          <div
            v-for="(action, index) in formData.actionConfig.actions"
            :key="action.__id"
          >
            <Card class="action-card mb-4">
              <template #title>
                <div class="flex items-center justify-between">
                  <span>{{
                    getActionNodeDefinition(action.node)?.nodeLabel
                  }}</span>
                  <Button type="link" danger @click="removeAction(index)"
                    ><DeleteOutlined
                  /></Button>
                </div>
              </template>
              <div
                v-if="getActionNodeDefinition(action.node)?.params.length === 0"
                class="text-gray-400"
              >
                无参数配置
              </div>
              <div
                v-for="param in getActionNodeDefinition(action.node)?.params"
                :key="param.key"
                class="form-group"
              >
                <label>{{ param.paramLabel }}:</label>
                <Input
                  v-if="param.type === 'TEXT_INPUT'"
                  v-model:value="action[param.key]"
                />
                <Select
                  v-if="param.type === 'SELECT'"
                  v-model:value="action[param.key]"
                  :options="param.options"
                  class="w-full"
                />
                <Input.TextArea
                  v-if="param.type === 'TEXT_AREA'"
                  v-model:value="action[param.key]"
                />
              </div>
            </Card>
          </div>
        </Card>
      </div>

      <!-- Fixed Footer -->
      <div class="footer-actions">
        <Space>
          <Button @click="closeCurrentTab()">取消</Button>
          <Button type="primary" @click="saveRule">保存规则</Button>
        </Space>
      </div>
    </div>
    <div v-else class="flex h-full items-center justify-center text-gray-400">
      <span v-if="!isLoading">加载规则失败，或规则不存在。</span>
    </div>

    <!-- 添加节点 Modal -->
    <Modal v-model:open="isNodeSelectorVisible" title="选择动作" :footer="null">
      <Row :gutter="[16, 16]" class="mt-4">
        <Col :span="12" v-for="node in ACTION_NODES" :key="node.node">
          <Card hoverable @click="handleNodeSelected(node.node)">
            <Card.Meta :title="node.nodeLabel" />
          </Card>
        </Col>
      </Row>
    </Modal>
  </Page>
</template>

<style scoped>
.rule-config-panel {
  /* padding is now handled by Tailwind's p-6 class in the scrollable div */
  background-color: v-bind('token.colorBgContainer');
  border-radius: v-bind("token.borderRadiusLG + 'px'");
}

.config-section {
  margin-bottom: 16px;
}
.action-card {
  background-color: v-bind('token.colorBgLayout');
}
.form-group {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
}
.form-group label {
  flex: 0 0 100px;
  text-align: right;
  color: v-bind('token.colorTextSecondary');
}
.footer-actions {
  margin-top: 16px;
  padding: 16px 24px; /* Add padding to match the scrollable area */
  text-align: right;
  border-top: 1px solid v-bind('token.colorSplit');
}
</style>
